package com.asen.commons.core.listener;

import com.asen.commons.annotation.ServiceAction;
import com.asen.commons.core.base.domain.Core;
import com.asen.commons.utils.SpringUtil;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 服务操作类holder
 *
 * @author Gary
 * @version 1.0
 * @date 2019-12-05
 */
@Component
public class ServiceActionHolder {

    private Map<Class, List<ServiceActionListener>> holders;

    public List<ServiceActionListener> getListeners(Class<?> modelClazz) {
        if (holders == null) {
            init();
        }

        List<ServiceActionListener> listeners = new ArrayList<>();
        for (Map.Entry<Class, List<ServiceActionListener>> entry : holders.entrySet()) {
            if (entry.getKey().isAssignableFrom(modelClazz)) {
                listeners.addAll(entry.getValue());
            }
        }

        return listeners;
    }

    public void init() {
        if (holders == null) {
            synchronized (ServiceActionHolder.class) {
                if (holders == null) {
                    holders = new ConcurrentHashMap<>(20);
                    Map<String, ServiceActionListener> serviceBeans = SpringUtil.getBeansOfType(ServiceActionListener.class);
                    for (Map.Entry<String, ServiceActionListener> entry : serviceBeans.entrySet()) {
                        ServiceActionListener listener = entry.getValue();
                        if (listener == null) {
                            continue;
                        }

                        Class<?> modelClazz = Core.class;
                        if (listener.getClass().isAnnotationPresent(ServiceAction.class)) {
                            ServiceAction actionService = listener.getClass().getAnnotation(ServiceAction.class);
                            modelClazz = actionService.value();
                        }

                        List<ServiceActionListener> list = holders.get(modelClazz);
                        if (list == null) {
                            list = new ArrayList<>();
                            holders.put(modelClazz, list);
                        }

                        list.add(listener);
                    }
                }
            }
        }
    }
}
